home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / tc_tsr10.zip / REMOVE.C < prev    next >
Text File  |  1991-06-14  |  12KB  |  251 lines

  1. /*--------------------------------------------------------------------------*
  2.  | Author:                                                                  |
  3.  | Sherif El-Kassas        .       :.                                       |
  4.  | EB dept           \_____o__/ __________                                  |
  5.  | Eindhoven U of Tec       .. /                                            |
  6.  | The Netherlands            /             Email: elkassas@eb.ele.tue.nl   |
  7.  *--------------------------------------------------------------------------*/
  8.  
  9. /*--------------------------------------------------------------------------*
  10.  | The author shall not be liable to the user for any direct, indirect      |
  11.  | or consequential loss arising from the use of, or inability to use,      |
  12.  | any program or file howsoever caused.  No warranty is given that the     |
  13.  | programs will work under all circumstances.                              |
  14.  *--------------------------------------------------------------------------*/
  15.  
  16. /*--------------------------------------------------------------------------*
  17.  | REMOVE.C                                                                 |
  18.  |   Removes a memory resident utility, and restores interrupt vectors.     |
  19.  |   Remove is supplied as is with no warranty, expressed or implied.       |
  20.  |   It is not copyrighted, either.                                         |
  21.  |   Usage: REMOVE <program name> <interrupt file>                          |
  22.  |   Compile with: TCC remove.c                                             |
  23.  *--------------------------------------------------------------------------*/
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <dos.h>
  28. #ifdef ANSI_LIB
  29. #define far
  30. #define huge
  31. #define near
  32. #endif
  33.  
  34. /*--------------------------------------------------------------------------*
  35.  |                         MACRO DEFINITIONS                                |
  36.  *--------------------------------------------------------------------------*/
  37.  
  38. #define FAR_WORD(seg, ofs)         (* (unsigned far *) MK_FP(seg, ofs) )
  39.  
  40. #define FAR_CHAR(seg, ofs)         (* (char far *) MK_FP(seg, ofs) )
  41.  
  42. #define IS_ARENA_HEADER(seg)       ( FAR_CHAR(seg, 0) == 'M' )
  43.  
  44. #define IS_PSP_ARENA_HEADER(seg)   ( FAR_WORD(seg, 1) == ((seg)+1) )
  45.  
  46. #define IS_FIRST_ARENA_HEADER(seg) ( IS_ARENA_HEADER( seg )  &&  \
  47.                                      IS_PSP_ARENA_HEADER( seg ) )
  48.  
  49. #define IS_LAST_ARENA_HEADER(seg)  ( FAR_CHAR(seg, 0) == 'Z')
  50.  
  51. #define ARENA_SIZE(seg)            ( FAR_WORD(seg, 3) )
  52.  
  53. #define NEXT_ARENA_HEADER(seg)     ( ARENA_SIZE(seg) + (seg) + 1 )
  54.  
  55.  
  56. typedef unsigned int word;                    /* define 'word' data type    */
  57.  
  58. #define cli()     __cli__()
  59. #define sti()     __sti__()
  60. #define INTR(x)   __int__(x)
  61.  
  62. #define ERROR_MESSAGE  "Invalid number of parameters\n\n"  \
  63.                        "Usage: REMOVE <program name>.<ext>" \
  64.                        " <interrupt file name>\n"
  65.  
  66. /*--------------------------------------------------------------------------*
  67.  | halt                                                                     |
  68.  |   Terminate program, and return rc. Use with care, halt dose not do any  |
  69.  |   cleaning up. (interrupt vectors are not restored, buffers not flushed, |
  70.  |   ... etc)                                                               |
  71.  *--------------------------------------------------------------------------*/
  72.  
  73. void halt(int rc){
  74.   _AL = rc; _AH = 0x4C;
  75.   INTR(0x21);
  76. }/* halt */
  77.  
  78. /*--------------------------------------------------------------------------*
  79.  | reset_timer                                                              |
  80.  |   Reset timer to normal speed                                            |
  81.  *--------------------------------------------------------------------------*/
  82.  
  83. void reset_timer(void){
  84.   cli();
  85.   outportb(0x43, 0x36);
  86.   outportb(0x40, 0);
  87.   outportb(0x40, 0);
  88.   sti();
  89. }/* reset_timer */
  90.  
  91. /*--------------------------------------------------------------------------*
  92.  | reset_display                                                            |
  93.  *--------------------------------------------------------------------------*/
  94. void reset_display(void){
  95.   _AX = 0x0F00; INTR(0x10); /* get video mode */
  96.   _AH = 0; INTR(0x10); /* set video mode ! */
  97. }/* reset_display */
  98.  
  99.  
  100. /*--------------------------------------------------------------------------*
  101.  | first_mcb                                                                |
  102.  |   returns the segment address of the first (interesting) memory control  |
  103.  |   block. (it skips command.com ??)                                       |
  104.  *--------------------------------------------------------------------------*/
  105.  
  106. word first_mcb(void){
  107.   register word seg;
  108.  
  109.   for ( seg = 0; ! IS_FIRST_ARENA_HEADER( seg ); seg++ ) ;
  110.   seg = NEXT_ARENA_HEADER(seg); /* skip the first block (command.com ?) */
  111.   return(seg);
  112. }/* first_mcb */
  113.  
  114.  
  115. /*--------------------------------------------------------------------------*
  116.  | get_program_name                                                         |
  117.  |   Search environment space and, if successful return a pointer to the    |
  118.  |   program name (no path), otherwise return a NULL pointer.               |
  119.  |   The program name is stored in a static area that is overwritten each   |
  120.  |   call !                                                                 |
  121.  *--------------------------------------------------------------------------*/
  122.  
  123. char *get_program_name(word psp){
  124.   static   char buffer[80];        /* static buffer for returned string     */
  125.   char     far  *env_ptr;          /* far pointer to environment space      */
  126.   register word env_owner;         /* actual owner's psp                    */
  127.   register char *p=buffer+79;      /* pointer to end of buffer              */
  128.  
  129.   env_owner = FAR_WORD(FAR_WORD(psp, 0x2c) - 1, 1); /* get actual owner's   */
  130.                                                     /* psp from environment */
  131.   if ( (env_owner == psp) && (_osmajor >= 3) ){
  132.     env_ptr = MK_FP( FAR_WORD(psp, 0x2c), 0 ); /* point to environment      */
  133.     while(* (int far *) env_ptr++) ;          /* scan to end of environment */
  134.     env_ptr += 3; /* jump over 2nd byte of integer zero and 2 bytes number  */
  135.                   /* of strings field                                       */
  136.  
  137.     while (*env_ptr) env_ptr++;                   /* seek to end of string  */
  138.  
  139.     while (*env_ptr != '\\' && p > buffer) /* copy name (only) to buffer    */
  140.       *p-- = *env_ptr--;
  141.  
  142.     return(++p);                         /* return pointer to program name  */
  143.   }
  144.   else return(NULL);                /* return NULL if name can't be found   */
  145. }/* get_program_name */
  146.  
  147. /*--------------------------------------------------------------------------*
  148.  | get_program_psp_seg                                                      |
  149.  |   Searches for a TSR called 'prog_name', if successful returns the PSP   |
  150.  |   segment address of the program (not the MCB address), otherwise it     |
  151.  |   returns 0.                                                             |
  152.  *--------------------------------------------------------------------------*/
  153. word get_program_psp_seg(char *prog_name, register word seg){
  154.   register char *name;                      /* pointer to retrieved names ! */
  155.  
  156.   while ( ! IS_LAST_ARENA_HEADER( seg ) ){
  157.     if ( IS_PSP_ARENA_HEADER( seg ) && (_psp != (seg+1)) ){
  158.       name = get_program_name(seg+1);
  159.       if ( (*prog_name=='*') ||   /* Eindhoven 17/5/89 */
  160.          (strcmpi(name, prog_name) == 0) /* compare strings ignoring case   */
  161.          )
  162.         return(seg+1);            /* if a match is found return PSP address */
  163.     }
  164.     seg = NEXT_ARENA_HEADER( seg );
  165.   }
  166.   return(0);                                 /* return 0 if TSR not found   */
  167. }/* get_program_psp_seg */
  168.  
  169. /*--------------------------------------------------------------------------*
  170.  | get_last_program_psp_seg                                                 |
  171.  |   Return the PSP segment address of the LAST TSR in memory, if non exist |
  172.  |   it returns 0.                                                          |
  173.  |   (Eindhoven 23-8-1990 )                                                 |
  174.  *--------------------------------------------------------------------------*/
  175. word get_last_program_psp_seg(register word seg){
  176.   register word last_seg=0;
  177.   while ( ! IS_LAST_ARENA_HEADER( seg ) ){
  178.     if ( IS_PSP_ARENA_HEADER(seg) && _psp != seg+1 )
  179.       last_seg = seg+1;
  180.     seg = NEXT_ARENA_HEADER( seg );
  181.   }
  182.   return( last_seg );
  183. }/*get_last_program_psp_seg*/
  184.  
  185. /*--------------------------------------------------------------------------*
  186.  | free_mem                                                                 |
  187.  |   Scan memory, starting at 'seg', and free any blocks that are owned by  |
  188.  |   'prog_seg'                                                             |
  189.  *--------------------------------------------------------------------------*/
  190.  
  191. void free_mem(register word prog_seg, register word seg){
  192.   while ( ! IS_LAST_ARENA_HEADER( seg ) ){
  193.     if (FAR_WORD(seg, 1) == prog_seg)
  194.       freemem(seg+1);
  195.     seg = NEXT_ARENA_HEADER( seg );
  196.   }
  197. }/* free_mem */
  198.  
  199.  
  200. /*--------------------------------------------------------------------------*
  201.  | set_interrupts                                                           |
  202.  |   Reads an interrupt table from 'intr_file_name', and copies it to the   |
  203.  |   system interrupt table.                                                |
  204.  *--------------------------------------------------------------------------*/
  205.  
  206. void set_interrupts(char *intr_file_name){
  207.   static  void interrupt (* intr_buffer[0x100])(); /* buffer to hold ints.  */
  208.   FILE          *file;
  209.   register word i;
  210.  
  211.   if ((file = fopen(intr_file_name, "rb")) != NULL){
  212.     fread(intr_buffer, sizeof(void interrupt (*)()), 0x100, file);
  213.     fclose(file);
  214.  
  215.     for(i=0; i<0x100; i++)
  216.       setvect(i, intr_buffer[i]);
  217.   }
  218. }/* set_interrupts */
  219.  
  220.  
  221. /*--------------------------------------------------------------------------*
  222.  | main                                                                     |
  223.  |   Locates program 'av[1]', copies interrupt vectors from 'av[2]' (file), |
  224.  |   and frees all memory blocks that belong to 'av[1]'                     |
  225.  *--------------------------------------------------------------------------*/
  226.  
  227. main(int ac, char **av){
  228.   register word seg;
  229.   register word prog_psp_seg;
  230.  
  231.   if (ac > 2){
  232.     seg = first_mcb();                                /* locate first MCB   */
  233.  
  234.     if (*av[1]=='*')  /*Eindhoven 23-8-1990*/
  235.          prog_psp_seg = get_last_program_psp_seg(seg);
  236.     else prog_psp_seg = get_program_psp_seg(av[1], seg);
  237.  
  238.     if (prog_psp_seg != 0){                /*if program is loaded, then     */
  239.       reset_timer();                       /* reset timer to normal speed   */
  240.       set_interrupts(av[2]);               /* restore interrupt vectors     */
  241.       reset_display();                     /* reset display characteristics */
  242.       free_mem(prog_psp_seg, seg);         /* free memory                   */
  243.       halt(0);             /* exit program without restoring the interrupts */
  244.                            /* saved by TC's start up code !                 */
  245.     }
  246.     else printf("Program %s not found\n", av[1]);
  247.   }
  248.   else printf(ERROR_MESSAGE);      /* Invalid number of parameters          */
  249.  
  250. }/* main */
  251.